/**
    GpsNetwork lets you download files and log some system parameters from NetRs DGPS receivers.

    Copyright (C) 2009  Eduardo Maureira

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    email:emaureir@gmail.com
 */
package process;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import netrs.Config;

import org.apache.log4j.Logger;


/**
 */
public class SystemCall extends Thread{
	private static final Logger logger = Logger.getLogger(SystemCall.class);
	private String[] comando;
	private Process proceso;
	private String cliente;
	private SystemCall next;
	private String feedBack;

	/**
	 * Pool en el cual debe ejecutarse esta tarea.
	 */
	private String poolId;

	/**
	 * listeners de los eventos generados por esta clase
	 */
	private ArrayList<IEventoSystemCallListener> listeners;

	public SystemCall(String[] _comando, String cliente, String poolID, String feedBack)
	{
		this.comando = _comando;
		this.proceso = null;
		this.listeners = new ArrayList<IEventoSystemCallListener>();
		this.cliente = cliente;
		this.poolId = poolID;
		this.feedBack = feedBack;
		next = null;
	}

	public void run()
	{
		int valorRetorno;
		valorRetorno = -1;
		//################
		EventoSystemCall evt;
		evt = new EventoSystemCall(this,EventoSystemCall.STARTED, 0);
		dispatchMyEvent(evt);
		//################
		logger.info("Ejecutando SystemCall="+this.toString());
		try {

			this.proceso = Runtime.getRuntime().exec(comando);
			//################
			InputStream stdErr, stdIn;
			OutputStream stdOut;
			stdErr = this.proceso.getErrorStream();
			stdOut = this.proceso.getOutputStream();
			stdIn = this.proceso.getInputStream();
			int valor;
			valor = 0;
			do {
				try {
					valor = stdErr.read();
					//System.out.print(  (char)valor);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}				
			} while (valor!=-1);
			try {
				valorRetorno = this.proceso.waitFor();
				logger.info("valorRetorno= "+valorRetorno);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			stdErr.close();
			stdIn.close();
			stdOut.close();
			
			logger.info("SystemCall finalizado");
			//################
			evt = new EventoSystemCall(this,EventoSystemCall.TERMIMATED, valorRetorno);
			dispatchMyEvent(evt);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.debug("--SystemCall IOException--"+e.getMessage());
		}
		logger.info("Finalizando SystemCall");
		if (next!=null)
		{	
			Pool poolLocal;
			poolLocal = Config.getLocker().get(next.poolId);
			if (poolLocal!=null)
			{
				poolLocal.add(next);
			}
		}
	}

	public void addMyEventListener( IEventoSystemCallListener evento ) {
		if (evento!=null)
		{
			listeners.add( evento );
		}
	}

	private void dispatchMyEvent(EventoSystemCall me) 
	{ 
		me.setCliente(this.cliente);
		for ( int j = 0; j < listeners.size(); j++ ) {
			IEventoSystemCallListener mel = (IEventoSystemCallListener) listeners.get(j);
			if ( mel != null ) {

				mel.handleSystemCallEvent( me );
			}
		}		  
	} // end dispatchMyEvent();	

	/**
	 * Pool en el cual debiera ejecutarse esta tarea
	 * @return the poolId
	 */
	public String getPoolId() {
		return poolId;
	}

	/**
	 * @param poolId the poolId to set
	 */
	public void setPoolId(String poolId) {
		this.poolId = poolId;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Test01();
	}

	public static void Test01 (){
		SystemCall ScTeqc;

		String[] sentence;
		StringBuilder sentencia;
		sentencia = new StringBuilder();
		//wget --no-clobber --output-document="D:\NetRsTest\200.68.55.28\200901\CNBA200901070000y.T00" "http://200.68.55.28:80/prog/Download?LoggedFile&path=/200901/CNBA200901070000y.T00"
		sentencia.append( "wget#--no-clobber#--output-document=\"D:\\NetRsTest\\CNBA\\200901\\CNBA200901070000z.T00\"#\"http://200.68.55.28:80/prog/Download?LoggedFile&path=/200901/CNBA200901070000z.T00\"");
		sentence = sentencia.toString().split("#");		


		ScTeqc = new SystemCall(sentence, "Test01", "WGET_T00","CNBA200901070000z.T00");		
		//ScTeqc = new SystemCall("teqc -help");		
		ScTeqc.start();
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		InputStream stdErrTeqc;
		//stdoutTeqc = ScTeqc.getProceso().getInputStream();
		stdErrTeqc = ScTeqc.getProceso().getErrorStream();
		int valor;
		valor = 0;
		do {
			try {
				valor = stdErrTeqc.read();
				System.out.print(  (char)valor);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} while (valor!=-1);
	}

	public Process getProceso() {
		return proceso;
	}

	public void setProceso(Process proceso) {
		this.proceso = proceso;
	}

	public String[] getComando() {
		return comando;
	}

	public void setComando(String[] comando) {
		this.comando = comando;
	}

	/**
	 * @return the cliente
	 */
	public String getCliente() {
		return cliente;
	}

	/**
	 * @param cliente the cliente to set
	 */
	public void setCliente(String cliente) {
		this.cliente = cliente;
	}

	/**
	 * @return the next
	 */
	public SystemCall getNext() {
		return next;
	}

	/**
	 * @param next the next to set
	 */
	public void setNext(SystemCall next) {
		this.next = next;
	}



	/**
	 * @return the feedBack
	 */
	public String getFeedBack() {
		return feedBack;
	}

	/**
	 * @param feedBack the feedBack to set
	 */
	public void setFeedBack(String feedBack) {
		this.feedBack = feedBack;
	}


	/* (non-Javadoc)
	 * @see java.lang.Thread#toString()
	 */
	@Override
	public String toString() {
		StringBuilder mensaje;
		mensaje = new StringBuilder ();
		mensaje.append("SystemCall cliente=");
		mensaje.append(cliente);
		mensaje.append("	poolID=");
		mensaje.append(poolId);
		mensaje.append("\n\r comando=");


		for (int i=0;i<comando.length;i++)
		{
			mensaje.append(comando[i]);
			mensaje.append(" ");

		}
		return mensaje.toString();
	}
}
